package com.dyson.jvm;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ClassName: MyClassLoader
 * @Date: 2020/7/6 16:55
 * @Author: WY
 * @Email: dysonwy@foxmail.com
 * @Desc: 自定义类加载器, 加载class文件
 */
public class MyClassLoader extends ClassLoader {

    private File classPathFile;

    public MyClassLoader() {
        String path = MyClassLoader.class.getResource("").getPath();
        // /G:/myStudy/demo/02-class-loader/target/classes/com/dyson/jvm/
        System.out.println("构造当前类路径:" + path);
        this.classPathFile = new File(path);
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
        MyClassLoader classLoader = new MyClassLoader();
        Class<?> clazz = classLoader.findClass("TestEntity");
        newInstance(clazz);
    }
    private static void newInstance(Class clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        Object o = clazz.newInstance();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            method.invoke(o);
        }
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //获取包名加类名
        String className = MyClassLoader.class.getPackage().getName() + "." + name;
        System.out.println("包名和类名:" + className);
        System.out.println("形参类名:" + name);
        if (classPathFile != null) {
            //获取class文件
            File classFile = new File(classPathFile, name.replace("\\.", "/") + ".class");
            if (classFile.exists()) {
                try (
                        FileInputStream fis = new FileInputStream(classFile);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ) {
                    byte[] buff = new byte[1024];
                    int len;
                    while ((len = fis.read(buff)) != -1) {
                        baos.write(buff, 0, len);
                    }
                    //调用类加载
                    return defineClass(className, baos.toByteArray(), 0, baos.size());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        throw new ClassNotFoundException();
    }
}
